#include "bmp280.h"
#include "i2c.h"
#include "usart.h"
#include "stm32f1xx_hal.h"
#include "string.h"
#include <stdio.h>

BMP280_CalibParams bmp280_calib;

void BMP280_Read_Calibration(I2C_HandleTypeDef *hi2c, uint8_t dev_addr)
{
    uint8_t calib[26] = {0};

    // 读取从 0x88 开始的 26 字节
    HAL_I2C_Mem_Read(hi2c, dev_addr << 1, 0x88, 1, calib, 26, HAL_MAX_DELAY);

    // 解析并填入结构体
    bmp280_calib.dig_T1 = (uint16_t)(calib[1] << 8) | calib[0];
    bmp280_calib.dig_T2 = (int16_t)(calib[3] << 8) | calib[2];
    bmp280_calib.dig_T3 = (int16_t)(calib[5] << 8) | calib[4];
    bmp280_calib.dig_P1 = (uint16_t)(calib[7] << 8) | calib[6];
    bmp280_calib.dig_P2 = (int16_t)(calib[9] << 8) | calib[8];
    bmp280_calib.dig_P3 = (int16_t)(calib[11] << 8) | calib[10];
    bmp280_calib.dig_P4 = (int16_t)(calib[13] << 8) | calib[12];
    bmp280_calib.dig_P5 = (int16_t)(calib[15] << 8) | calib[14];
    bmp280_calib.dig_P6 = (int16_t)(calib[17] << 8) | calib[16];
    bmp280_calib.dig_P7 = (int16_t)(calib[19] << 8) | calib[18];
    bmp280_calib.dig_P8 = (int16_t)(calib[21] << 8) | calib[20];
    bmp280_calib.dig_P9 = (int16_t)(calib[23] << 8) | calib[22];
    // 打印校准数据
    char buffer[200];
    snprintf(buffer, sizeof(buffer), "Calibration Data:\r\n"
                                     "dig_T1: %u\r\n"
                                     "dig_T2: %d\r\n"
                                     "dig_T3: %d\r\n"
                                     "dig_P1: %u\r\n"
                                     "dig_P2: %d\r\n"
                                     "dig_P3: %d\r\n"
                                     "dig_P4: %d\r\n"
                                     "dig_P5: %d\r\n"
                                     "dig_P6: %d\r\n"
                                     "dig_P7: %d\r\n"
                                     "dig_P8: %d\r\n"
                                     "dig_P9: %d\r\n",
             bmp280_calib.dig_T1, bmp280_calib.dig_T2, bmp280_calib.dig_T3,
             bmp280_calib.dig_P1, bmp280_calib.dig_P2, bmp280_calib.dig_P3,
             bmp280_calib.dig_P4, bmp280_calib.dig_P5, bmp280_calib.dig_P6,
             bmp280_calib.dig_P7, bmp280_calib.dig_P8, bmp280_calib.dig_P9);
    HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY); // Send calibration data over UART
    HAL_Delay(100);                                                               // Wait for the sensor to configure
}

void BMP280_Init(void)
{
    /*开机先Reset*/
    uint8_t data[2];
    data[0] = 0xE0;                                                               // Reset address
    data[1] = 0xB6;                                                               // Reset value
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDRESS << 1, data, 2, HAL_MAX_DELAY); // Send reset command
    HAL_Delay(100);                                                               // Wait for the sensor to reset
    /*读取设备ID*/
    uint8_t id = 0;
    uint8_t read_cmd = 0xD0;                                                           // Read command for device ID
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDRESS << 1, &read_cmd, 1, HAL_MAX_DELAY); // Send read command
    HAL_I2C_Master_Receive(&hi2c1, BMP280_ADDRESS << 1, &id, 1, HAL_MAX_DELAY);        // Read device ID
    if (id == 0x58)                                                                    // Check if the ID is correct
    {
        HAL_UART_Transmit(&huart2, (uint8_t *)"BMP280 found!\r\n", 14, HAL_MAX_DELAY);
    }
    /*配置传感器*/
    uint8_t config[2] = {0};
    config[0] = BMP280_REG_CTRL_MEAS;                                               // Control measurement register address
    config[1] = (Oversampling_2 << 5) | (Oversampling_16 << 2) | Normal_Mode;       // Set temperature oversampling skip
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDRESS << 1, config, 2, HAL_MAX_DELAY); // Send configuration command
    HAL_Delay(100);
    config[0] = BMP280_REG_CONFIG;                                                  // Configuration register address
    config[1] = (tsandby << 5) | (IIR_filter << 2);                                 // Set no SPI mode
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDRESS << 1, config, 2, HAL_MAX_DELAY); // Send configuration command
    HAL_Delay(100);                                                                 // Wait for the sensor to configure
    /*配置完成，传感器可以工作了*/
    HAL_UART_Transmit(&huart2, (uint8_t *)"BMP280 initialized successfully!\r\n", 34, HAL_MAX_DELAY); // Send success message
    /*读取校准数据*/
    BMP280_Read_Calibration(&hi2c1, BMP280_ADDRESS); // Read calibration data from BMP280
}

void BMP280_Read_Pressure(void)
{
    uint8_t data[6] = {0};
    uint8_t read_cmd = 0xF7;                                                                      // pressure data register address
    HAL_I2C_Master_Transmit(&hi2c1, BMP280_ADDRESS << 1, &read_cmd, 1, HAL_MAX_DELAY);            // Send read command
    HAL_I2C_Master_Receive(&hi2c1, BMP280_ADDRESS << 1, data, 6, HAL_MAX_DELAY);                  // Read pressure data
    int32_t adc_P = ((int32_t)data[0] << 12) | ((int32_t)data[1] << 4) | ((int32_t)data[2] >> 4); // Combine the three bytes into a single value
    int32_t adc_T = ((int32_t)data[3] << 12) | ((int32_t)data[4] << 4) | ((int32_t)data[5] >> 4); // Combine the three bytes into a single value

    // Calculate the actual pressure using the calibration coefficients (not shown here)
    // For simplicity, we will just print the raw ADC value
    char buffer[100];
    snprintf(buffer, sizeof(buffer), "Raw temperature ADC Value: %ld\r\nRaw Pressure ADC value: %ld\r\n", adc_T, adc_P); // Format the string with ADC values
    HAL_UART_Transmit(&huart2, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);                                        // Send pressure data
}
